/**
 * InvientEngine - Experimental physics and graphics library
 * Copyright (C) 2011  Shane Transue
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see http://www.gnu.org/licenses/gpl.html
 *
 * No line in this file should exceed 80 characters in width.
 */

package com.invient.core.perf;

/**
 * The Tuplef class represents a list of float values. The implementation of
 * this class is based on performance; therefore, where possible, the
 * implementations of specific methods are focused on reducing their complexity
 * and improving their performance. Tuples are not implementations of any 
 * List interface, and therefore do not behave as lists, their purpose is much
 * more specific to holding a constant number of values.
 */
public class Tuplef extends Tuple
{
    protected static final float INITIALIZATION_VALUE = 0.0f;
    protected float[] data;
    
    /**
     * Creates a Tuple with null data. Tuples are not implementations of
     * a List interface.
     */
    protected Tuplef() {
        this.data = null;
    }
    
    /**
     * Creates a Tuple from the provided data. The values from the provided
     * array are copied into the Tuple.
     *
     * @param data The data that will be used to initialize the Tuple.
     * @throws IllegalArgumentException If the input data array is null or
     * if its length is zero.
     */
    public Tuplef(float[] data) {
        if ( data == null )
            throw new IllegalArgumentException("[Tuplef] Error creating" + 
                " Tuplef with null data array");
        if ( data.length == 0 )
            throw new IllegalArgumentException("[Tuplef] Error creating" +
                " Tuplef with data array of size: " + data.length);
        
        this.data = new float[data.length];
        for ( int i = 0; i < this.data.length; i++ )
            this.data[i] = data[i];
    }
    
    /**
     * This method returns the data held by this Tuple.
     *
     * @return Returns a float array representation of the data held by this
     * Tuple.
     */
    public float[] getData() {
        return this.data;
    }
    
    /**
     * This method clears the values held in this Tuple to the constant
     * INITIALIZATION_VALUE.
     */
    public void clear() {
        for ( int i = 0; i < this.data.length; i++ )
            this.data[i] = INITIALIZATION_VALUE;
    }
    
    /**
     * This method sets the value at the specified index to the provided value.
     *
     * @param index The index of the element to be changed.
     * @param value The value that will replace the element at the provided
     * index.
     */
    public void set(int index, float value) {
        if ( index < 0 || index >= this.data.length )
            throw new ArrayIndexOutOfBoundsException("[Tuplef] Error cannot" +
                " set data value in Tuplef, the index was" +
                " out of bounds: " + index);
                
        this.data[index] = value;
    }
    
    /**
     * This method returns the value at the provided index in this Tuple.
     * 
     * @param index The index of the element to retrieve.
     * @return Returns the value at the provided index.
     */
    public float get(int index) {
        if ( index < 0 || index >= this.data.length )
            throw new ArrayIndexOutOfBoundsException("[Tuplef] Error cannot" +
                " return value from Tuplef, the index was" +
                " out of bounds: " + index);
                
        return this.data[index];
    }
    
    /**
     * This method returns the String representation of a Tuple. The format
     * of the output is as follows:<br /><br />
     *
     * [ \t value1 \t ... \t valueN \t ]
     *
     * @return Returns the String representation of a Tuple.
     */
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("[\t");
        for ( int i = 0; i < this.data.length; i++ )
            builder.append(this.data[i] + "\t");
        builder.append("]");
        return builder.toString();
    }
}